package com.jandar.spider.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jandar.spider.config.SeleniumConfig;
import com.jandar.spider.config.property.SpiderConfig;
import com.jandar.spider.entity.PunishEntity;
import com.jandar.spider.mapper.PunishMapper;
import com.jandar.spider.utils.OkHttpUtils;
import com.jandar.spider.utils.RegularUtils;
import com.jandar.spider.utils.SeleniumUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.WebDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
public class PunishTask{
    @Autowired
    private PunishMapper mapper;
    @Autowired
    private OkHttpUtils okHttpUtils;
    private final static AtomicInteger producerCount = new AtomicInteger(0);
    private final static AtomicInteger repeatCount = new AtomicInteger(0);
    public final static AtomicBoolean run = new AtomicBoolean((false));
    private final static BlockingQueue<PunishEntity> dataQueue = new LinkedBlockingDeque<>();

    @Autowired
    private SpiderConfig spiderConfig;


    @Async("taskExecutor")
    public void producer(WebDriver driver, String url) {
        run.set(true);
        repeatCount.set(0);
        producerCount.getAndIncrement();
        try {
            produce(driver, url);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.close();
            log.info("produce over");
            producerCount.getAndDecrement();
        }
    }

    @Async("taskExecutor")
    public void consumer() {
        do {
            if (dataQueue.isEmpty()) {
                try {
                    log.info("让队列拿数据....，休息1分钟");
                    Thread.sleep(60000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                PunishEntity punishEntity = dataQueue.poll();
                try {
                    QueryWrapper<PunishEntity> queryWrapper = new QueryWrapper<PunishEntity>().eq("punish_number", punishEntity.getPunishNumber());
                    List<PunishEntity> punishEntityList = mapper.selectList(queryWrapper);
                    if (punishEntityList.isEmpty()) {
                        log.info("插入成功:{}", punishEntity.getPunishNumber());
                    } else {
                        mapper.delete(queryWrapper);
                        log.info("重复数据数量 " + repeatCount.incrementAndGet());
                    }
                    mapper.insert(punishEntity);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } while (run.get());
        log.info("insert结束");
    }

    protected void produce(WebDriver driver, String url) {
        SeleniumUtil.to(driver, url);
        while (run.get()) {
            String html = SeleniumUtil.findElement(driver, "/html").getAttribute("outerHTML");
            Element body = Jsoup.parse(html).body();
            Elements tr = body.select("#xzcf_1 > table > tbody > tr");

            if (tr == null || tr.size() == 0) {
                return;
            }
            if (repeatCount.get() > spiderConfig.getSpider().getAllowRepeatCount()) {
                run.set(false);
                return;
            }
            tr.forEach(trs -> {
                PunishEntity entity = new PunishEntity();
                Elements td = trs.select("td");
                entity.setDetailPageUrl("http://www.zjzwfw.gov.cn" + td.get(0).select("a").attr("href"));
                entity.setCaseTitle(td.get(0).text());
                entity.setPenaltyObject(td.get(1).text());
                entity.setPunishNumber(td.get(2).text());
                entity.setPunishTime(td.get(3).text());
                try {
                    String htmlData = okHttpUtils.okhttpGet(entity.getDetailPageUrl());
                    if (StringUtils.hasLength(htmlData)) {
                        entity.setHtmlData(htmlData);
                        String dpt = Jsoup.parse(htmlData).body().select("table.xzcf_bg > tbody > tr:nth-child(3) > td.xzcf_xx").text();
                        String content = Jsoup.parse(htmlData).body().select("td.xzcf_jds  p").text();
                        entity.setArea(RegularUtils.Matcher_getString(dpt, "【(.+?)】", 1));
                        entity.setDepartment(dpt);
                        entity.setContent(content);
                    }
                } catch (Exception e) {
                    log.error("请求详情网页数据失败,失败原因:{}", e.toString());
                    e.printStackTrace();
                }
                entity.setSpiderTime(LocalDateTime.now());
                dataQueue.add(entity);
                log.info("当前队列数量:{}", dataQueue.size());
                try {
                    log.info("防止被封号5s请求一次");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            SeleniumUtil.clickByXpath(driver, "//*[@id=\"xzcf_1\"]/div/ul/li[4]");
        }
    }
}
